package ui.dnd;

import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import ui.*;

import javax.swing.*;

/**
 * Created with IntelliJ IDEA.
 * User: Deshun
 * Date: 2/18/13
 * Time: 11:12 AM
 * To change this template use File | Settings | File Templates.
 */
public class RowDropTargetListener implements DropTargetListener, DragGestureListener {

    //TODO make the ROW visually change position when the "row on cursor" hovers over the current row.
    //Main issue is the drop target is the rowlist which is covered by row. Therefore you need a space between rows so a row can be dropped.
    //to implement that feature might have to rewrite the drag and drop.

    private final FormPanel formPanel;

    private static final Cursor dropableCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
    private static final Cursor notDropableCursor = Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);

    public RowDropTargetListener(FormPanel base) {
        this.formPanel = base;
    }

    @Override
    public void dragGestureRecognized(DragGestureEvent dge) {
        System.out.println(SwingUtilities.getRootPane(formPanel.getPanel()));
    }

    @Override
    public void dragEnter(DropTargetDragEvent dtde) {
        if ( isDragOk(dtde) ) {

        }
    }

    @Override
    public void dragOver(DropTargetDragEvent dtde) {
    }

    @Override
    public void dropActionChanged(DropTargetDragEvent dtde) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void dragExit(DropTargetEvent dte) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    //TODO customise this method
    boolean isDragOk(DropTargetDragEvent dtde) {
        DataFlavor[] flavors = { null };
        try {
            flavors[0] = FormPanel.getDragAndDropRowDataFlavor();
        } catch ( Exception e ) {
            return false;
        }

        DataFlavor chosen = null;
        for ( int i = 0; i < flavors.length; i++ ) {
            if ( dtde.isDataFlavorSupported(flavors[i]) ) {
                chosen = flavors[i];
                break;
            }
        }

        if ( chosen == null ) {
            return false;
        }

        // the actions specified when the source
        // created the DragGestureRecognizer
        int sa = dtde.getSourceActions();

        // we're saying that these actions are necessary
        if ( ( sa & DnDConstants.ACTION_COPY ) == 0 )
            return false;
        return true;
    }

    //TODO Check this method
    @Override
    public void drop(DropTargetDropEvent dtde) {

        //this.formPanel.setCursor(Cursor.getDefaultCursor());

        DataFlavor flavor = null;

        Object transferableObj = null;
        Transferable transferable = null;

        System.out.println("Trying to drop");
        try {
            flavor = FormPanel.getDragAndDropRowDataFlavor();

            transferable = dtde.getTransferable();
            DropTargetContext c = dtde.getDropTargetContext();

            if (transferable.isDataFlavorSupported(flavor))
                transferableObj = dtde.getTransferable().getTransferData(flavor);
        } catch (Exception ex) {
            System.out.println("Drop failed");
        }

        if (transferableObj == null) {
            return;
        }

        FormRow droppedPanel = (FormRow )transferableObj;

        final int dropYLoc = dtde.getLocation().y;

        Map<Integer, FormRow> yLocMapForPanels = new HashMap<Integer, FormRow>();
        yLocMapForPanels.put(dropYLoc, droppedPanel);

        for (FormRow nextPanel : formPanel.getRows()) {

            int y = nextPanel.getPanel().getY();

            if (!nextPanel.equals(droppedPanel)) {
                yLocMapForPanels.put(y, nextPanel);
            }
        }

        java.util.List<Integer> sortableYValues = new ArrayList<Integer>();
        sortableYValues.addAll(yLocMapForPanels.keySet());
        Collections.sort(sortableYValues);

        java.util.List<FormRow> orderedPanels = new ArrayList<FormRow>();
        for (Integer i : sortableYValues) {
            orderedPanels.add(yLocMapForPanels.get(i));
        }

        java.util.List<FormRow> inMemoryPanelList = this.formPanel.getRows();
        inMemoryPanelList.clear();
        inMemoryPanelList.addAll(orderedPanels);

        this.formPanel.explode().revalidate();
        System.out.println("Drop done");
    }
}
